#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Priority.hh"
using namespace std;
using namespace log4cpp;

int main(int argc, char** argv) {
    //采用指针形式创建目的地对象(此处以标准输出流为目的地，输出到终端)
    //第一个参数是对目的地去一个名字（与配置文件有关）
    //第二个是指向通用输入流对象的指针
    //一个基类指针指向了派生类对象
	Appender *appender1 = new OstreamAppender("console", &cout);
    //目的地对象通过setLayout函数设置布局，参数为布局对象
    //setLayout需要的参数是Layout* 
    //Layout * p = new BasicLayout();
	appender1->setLayout(new BasicLayout());


    //创建目的地对象（文件）
    //第一个参数对目的地取名字
    //第二个参数是保存日志的文件名
	Appender *appender2 = new FileAppender("default", "program.log");
	appender2->setLayout(new BasicLayout());

    //使用getRoot方法创建模块对象（日志来源）
    //并用引用绑定对象
	Category& root = Category::getRoot();
    //设置日志系统的优先级
	root.setPriority(Priority::WARN);
    //为模块对象添加目的地（此处是通用输出流）
	root.addAppender(appender1);

    //getInstance函数的参数是对日志来源取的名字
	Category& sub1 = Category::getInstance(string("sub1"));
    //叶模块对象又添加了目的地（此处是文件）
	/* sub1.setPriority(Priority::FATAL); */
	sub1.addAppender(appender2);

	// use of functions for logging messages
	root.error("root error");
	root.info("root info");
	sub1.error("sub1 error");
	sub1.warn("sub1 warn");
    sub1.emerg("sub1 emerg");

	// printf-style for logging variables
	root.warn("%d + %d == %s ?", 1, 1, "two");

	// use of streams for logging messages
	root << log4cpp::Priority::ERROR << "Streamed root error";
	root << log4cpp::Priority::INFO << "Streamed root info";
	sub1 << log4cpp::Priority::ERROR << "Streamed sub1 error";
	sub1 << log4cpp::Priority::WARN << "Streamed sub1 warn";

	// or this way:
	root.errorStream() << "Another streamed error";

	return 0;
}
